const indexedDB = window.indexedDB;

const name = 'threejs-editor';
const version = 1;

let database: IDBDatabase | undefined;

type T = number | string | boolean | object | null;

const REGEXP = /\d\d:\d\d:\d\d/; // Matches HH:MM:SS

export const storage = {
  init: (callback: () => void) => {
    const request = indexedDB.open(name, version);
    request.onupgradeneeded = function () {
      const db = this.result;
      if (db.objectStoreNames.contains('states') === false) {
        db.createObjectStore('states');
      }
    };

    request.onsuccess = function () {
      database = this.result;
      callback();
    };

    request.onerror = (event) => {
      console.error('IndexedDB', event);
    };
  },

  get: (callback: (result: T) => void) => {
    if (database === undefined) return;
    const transaction = database.transaction(['states'], 'readonly');
    const objectStore = transaction.objectStore('states');
    const request = objectStore.get(0);
    request.onsuccess = function () {
      callback(this.result);
    };
  },

  set: (data: T) => {
    if (database === undefined) return;
    const start = performance.now();
    const transaction = database.transaction(['states'], 'readwrite');
    const objectStore = transaction.objectStore('states');
    const request = objectStore.put(data, 0);
    request.onsuccess = () => {
      console.log(
        `[${REGEXP.exec(new Date().toDateString())?.[0]}]`,
        `Saved state to IndexedDB. ${(performance.now() - start).toFixed(2)}ms`,
      );
    };
  },

  clear: () => {
    if (database === undefined) return;

    const transaction = database.transaction(['states'], 'readwrite');
    const objectStore = transaction.objectStore('states');
    const request = objectStore.clear();
    request.onsuccess = () => {
      console.log(`[${REGEXP.exec(new Date().toDateString())?.[0]}]`, 'Cleared IndexedDB.');
    };
  },
};
